جزوه · فصل دوم · جلسه ۲۷ · کتابخانه‌ها و دستور ldd ← بازگشت به فهرست
📘 فصل دوم · جلسه ۲۷ کتابخانه‌ها و دستور ldd
📅 تاریخ: سه‌شنبه، ۲۰ مرداد ۱۴۰۵ 👤 مدرس: محمد عابدینی 🐚 Zsh · 🐧 Debian (کالی) · 📦 Red Hat

▍ کتابخانه (Library) چیست؟

در لینوکس، کتابخانه (Library) مجموعه‌ای از توابع (Functions) است که برنامه‌ها می‌توانند از آنها استفاده کنند. توابع، قطعه‌های کد مستقلی هستند که کارهای خاصی را انجام می‌دهند، مانند باز کردن یک فایل، خواندن داده، یا محاسبه یک مقدار.

🔑 مزیت اصلی کتابخانه‌ها:

به جای اینکه هر برنامه این توابع را داخل خودش داشته باشد، همه برنامه‌ها از یک کتابخانه مشترک استفاده می‌کنند. این کار باعث صرفه‌جویی در فضا و سهولت به‌روزرسانی می‌شود.

▍ انواع کتابخانه در لینوکس

🔵 کتابخانه Static

  • در زمان کامپایل کپی می‌شود.
  • اندازه برنامه بزرگتر است.
  • به‌روزرسانی نیاز به کامپایل مجدد دارد.
  • پسوند: .a (Archive)

🔴 کتابخانه Shared (Dynamic)

  • در زمان اجرا (Runtime) بارگذاری می‌شود.
  • اندازه برنامه کوچکتر است.
  • به‌روزرسانی بدون کامپایل مجدد امکان‌پذیر است.
  • پسوند: .so (Shared Object)
💡 نکته:

در ویندوز، کتابخانه‌های پویا با پسوند .dll (Dynamic Linked Library) شناخته می‌شوند که معادل .so در لینوکس هستند.

▍ محل قرارگیری کتابخانه‌ها

سیستم برای پیدا کردن کتابخانه‌ها از ترتیب زیر پیروی می‌کند:

  1. متغیر محیطی LD_LIBRARY_PATH (اولویت اول)
  2. مسیرهای PATH برنامه
  3. پوشه /etc/ld.so.conf.d/ (فایل‌های کانفیگ)
  4. فایل /etc/ld.so.conf (کانفیگ اصلی)
  5. پوشه‌های /lib*/ و /usr/lib*/ (پیش‌فرض)
📌 مثال:

برای مشاهده مسیرهای جستجوی کتابخانه، از دستور زیر استفاده کنید:

┌──(ya3in㉿kali)-[~] └─$ ldconfig -v

توضیح: دستور ldconfig -v مسیرهای جستجوی کتابخانه را به همراه نسخه‌های موجود نمایش می‌دهد.

▍ دستور ldd (نمایش وابستگی‌های کتابخانه‌ای)

ldd مخفف List Dynamic Dependencies است و کتابخانه‌های پویا (Shared Libraries) که یک برنامه به آنها نیاز دارد را نمایش می‌دهد.

📌 ساختار کلی:
ldd [options] program

توضیح: program نام برنامه‌ای است که می‌خواهیم وابستگی‌های کتابخانه‌ای آن را بررسی کنیم.

• مثال عملی با دستور ls

ابتدا مسیر دقیق ls را با whereis پیدا می‌کنیم:

┌──(ya3in㉿kali)-[~] └─$ whereis ls ls: /usr/bin/ls /usr/share/man/man1/ls.1.gz

توضیح: whereis مسیر فایل اجرایی، صفحات راهنما و سورس فایل را پیدا می‌کند. در اینجا /usr/bin/ls مسیر فایل باینری است.

سپس با ldd وابستگی‌های آن را بررسی می‌کنیم:

┌──(ya3in㉿kali)-[~] └─$ ldd /usr/bin/ls linux-vdso.so.1 (0x00007ffd21d6a000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007fe2308a82000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe23085a000)
libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007fe2307c3000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe230ae7000)

توضیح خروجی:

• مثال با برنامه htop

┌──(ya3in㉿kali)-[~] └─$ which htop /usr/bin/htop └─$ ldd /usr/bin/htop linux-vdso.so.1 (0x00007ffe8a3a1000)
libncursesw.so.6 => /lib/x86_64-linux-gnu/libncursesw.so.6 (0x00007f8c4b1a0000)
libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007f8c4ae70000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8c4af00000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8c4b1c0000)

توضیح: htop به کتابخانه‌های libncursesw (برای رابط کاربری متنی) و libtinfo وابسته است.

▍ گزینه‌های مهم ldd

گزینه توضیح مثال
-v یا --verbose نمایش اطلاعات کامل و جزئیات بیشتر (شامل نسخه کتابخانه‌ها) ldd -v /bin/ls
-u یا --unused نمایش کتابخانه‌های غیرضروری که بارگذاری می‌شوند اما استفاده نمی‌شوند ldd -u /bin/ls
-r یا --function-relocs نمایش اطلاعات مربوط به توابع و آدرس‌های بازنشانی (Relocation) ldd -r /bin/ls

• مثال با گزینه -v

┌──(ya3in㉿kali)-[~] └─$ ldd -v /usr/bin/ls linux-vdso.so.1 (0x00007ffd21d6a000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007fe2308a82000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe23085a000)

Version information:
/usr/bin/ls:
libc.so.6 (GLIBC_2.34) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.33) => /lib/x86_64-linux-gnu/libc.so.6
libselinux.so.1 (SELINUX_1.0) => /lib/x86_64-linux-gnu/libselinux.so.1
...

توضیح: گزینه -v علاوه بر کتابخانه‌ها، اطلاعات نسخه (Version Information) را نیز نمایش می‌دهد که مشخص می‌کند برنامه از کدام نسخه کتابخانه‌ها استفاده می‌کند.

▍ chroot و کتابخانه‌ها

chroot (مخفف Change Root) یک تکنیک امنیتی است که ریشه (Root) سیستم را به یک دایرکتوری خاص تغییر می‌دهد. این کار باعث می‌شود که برنامه فقط به فایل‌های داخل آن دایرکتوری دسترسی داشته باشد. برای اینکه برنامه‌ها در محیط chroot به درستی کار کنند، باید کتابخانه‌های مورد نیاز آنها نیز در آن دایرکتوری وجود داشته باشند.

🔐 کاربردهای chroot:
  • محدود کردن کاربران SSH: کاربر فقط به دایرکتوری خودش دسترسی دارد.
  • محیط‌های تست (Sandbox): اجرای برنامه‌های ناشناخته در محیط ایزوله.
  • بازیابی سیستم: در صورت خرابی سیستم، می‌توان از chroot برای تعمیر استفاده کرد.
  • میزبانی وب: هر کاربر فقط به دایرکتوری وب‌سایت خود دسترسی دارد.
💡 مثال: محدود کردن کاربر SSH به دایرکتوری خاص

برای محدود کردن یک کاربر به دایرکتوری خانه خود، می‌توان از chroot در /etc/ssh/sshd_config استفاده کرد:

Match User username ChrootDirectory /home/username ForceCommand internal-sftp

توضیح: کاربر username فقط به دایرکتوری /home/username دسترسی خواهد داشت و نمی‌تواند به فایل‌های سیستمی دسترسی پیدا کند.

برای اینکه دستورات در محیط chroot کار کنند، باید کتابخانه‌های آنها را با ldd شناسایی و به دایرکتوری chroot کپی کنید.

▍ کاربرد عملی ldd در ایجاد chroot

فرض کنید می‌خواهید یک محیط chroot ساده برای کاربر ایجاد کنید که بتواند از دستور ls استفاده کند.

┌──(ya3in㉿kali)-[~] └─$ mkdir -p /jail/bin └─$ mkdir -p /jail/lib64 └─$ cp /bin/ls /jail/bin/ └─$ ldd /bin/ls linux-vdso.so.1 (0x00007ffd21d6a000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007fe2308a82000)
libcap.so.2 => /lib/x86_64-linux-gnu/libcap.so.2 (0x00007fe2307c3000)
libacl.so.1 => /lib/x86_64-linux-gnu/libacl.so.1 (0x00007fe2307b8000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe23085a000)
libpcre.so.1 => /lib/x86_64-linux-gnu/libpcre.so.1 (0x00007fe2307c3000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fe2307b8000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe230ae7000)
└─$ cp /lib64/{libselinux.so.1,libcap.so.2,libacl.so.1,libc.so.6,libpcre.so.1,libdl.so.2,ld-linux-x86-64.so.2} /jail/lib64/

توضیح گام‌به‌گام:

  1. mkdir -p /jail/bin → ایجاد دایرکتوری bin در زندان.
  2. mkdir -p /jail/lib64 → ایجاد دایرکتوری lib64 برای کتابخانه‌های ۶۴ بیتی.
  3. cp /bin/ls /jail/bin/ → کپی کردن دستور ls به زندان.
  4. ldd /bin/ls → شناسایی کتابخانه‌های مورد نیاز ls.
  5. cp /lib64/{...} /jail/lib64/ → کپی کردن کتابخانه‌های شناسایی شده به زندان.

حالا اگر با دستور chroot /jail /bin/ls وارد زندان شوید، می‌توانید از ls استفاده کنید.

▍ جمع‌بندی

✅ تمرین پیشنهادی:
  • با ldd وابستگی‌های کتابخانه‌ای برنامه‌های bash و python3 را بررسی کنید و کتابخانه‌های مورد نیاز را لیست کنید.
  • با ldconfig -v مسیرهای جستجوی کتابخانه را در سیستم خود ببینید.
  • با ldd -u /bin/ls کتابخانه‌های غیرضروری را شناسایی کنید (اگر وجود داشته باشند).
  • یک محیط chroot ساده ایجاد کنید و دستورات ls و date را به آن اضافه کنید.
  • در مورد chroot و کاربردهای آن در امنیت سرور مطالعه کنید.